#ifndef _UTILEX_DLLMODULE_HPP_
#define _UTILEX_DLLMODULE_HPP_

#include <crt_util.h>

#ifdef __cplusplus

class CDllmodule
{
public:
    struct STFunDesc {
        char* pFunName;
        size_t uOffFun;
    };

public:
    CDllmodule() { m_hMod.dispose(); }
    virtual ~CDllmodule() { UnLoad(); }

public:
    virtual void InitIAT()
    {
        STFunDesc* pFunDesc = GetFunDefs();

        while (pFunDesc->pFunName) {
            pFunDesc++;
        }
    }

    virtual int Load()
    {
        STFunDesc* pFunDesc = GetFunDefs();

        m_hMod = dllopen(m_szModuleName, RTLD_LAZY);

        rc_error(NULL != m_hMod, -1);

        while (string_stricmp(pFunDesc->pFunName, "null") != 0) {
            void* p = dllsym(m_hMod, pFunDesc->pFunName);

            SetFuncAddress(pFunDesc->uOffFun, p);
            if (!p) {
                rc_error(Exception(m_hMod, pFunDesc->pFunName) == 0, -1);
            }
            pFunDesc++;
        }

        return S_SUCCESS;
    }
    virtual void UnLoad() { m_hMod.dispose(); }
    virtual int IsLoaded() { return NULL != m_hMod; }
    virtual bool Exception(HMODULE hModule, const char* lpProcName)
    {
        debug_view("IImpModuleBase->Exception");
        return true;
    }
    virtual STFunDesc* GetFunDefs() = 0;
    virtual bool SetFuncAddress(size_t i, void* p) = 0;

protected:
    basic_tchar m_szModuleName[MAX_PATH];
    DynamiclibPtr m_hMod;
};

#endif //  __cplusplus

#endif
